package cool.doudou.doudada.cipher.algorithm.util;

import cool.doudou.doudada.cipher.algorithm.sm.Sm4Context;

import java.nio.charset.StandardCharsets;

/**
 * Sm4Util
 *
 * @author jiangcs
 * @since 2022/08/31
 */
public class Sm4Util {
    /**
     * 加密：ECB
     *
     * @param plaintext  明文
     * @param encryptKey 加密Key
     * @return 密文字符串
     */
    public static String encrypt(String plaintext, String encryptKey) {
        Sm4Context sm4Context = new Sm4Context();
        byte[] bytes = sm4Context.encryptByECB(hexToByte(plaintext), encryptKey.getBytes(StandardCharsets.UTF_8));
        return byteToHex(bytes);
    }

    /**
     * 解密：ECB
     *
     * @param ciphertext 密文
     * @param decryptKey 解密Key
     * @return 明文字符串
     */
    public static String decrypt(String ciphertext, String decryptKey) {
        Sm4Context sm4Context = new Sm4Context();
        byte[] bytes = sm4Context.decryptByECB(hexToByte(ciphertext), decryptKey.getBytes(StandardCharsets.UTF_8));
        return new String(bytes);
    }

    /**
     * 加密：CBC
     *
     * @param plaintext  明文
     * @param encryptKey 加密Key
     * @param iv         IV值
     * @return 密文字符串
     */
    public static String encrypt(String plaintext, String encryptKey, String iv) {
        Sm4Context sm4Context = new Sm4Context();
        byte[] bytes = sm4Context.encryptByCBC(hexToByte(plaintext), encryptKey.getBytes(StandardCharsets.UTF_8), iv.getBytes(StandardCharsets.UTF_8));
        return byteToHex(bytes);
    }

    /**
     * 解密：CBC
     *
     * @param ciphertext 密文
     * @param decryptKey 解密Key
     * @param iv         IV值
     * @return 明文字符串
     */
    public static String decrypt(String ciphertext, String decryptKey, String iv) {
        Sm4Context sm4Context = new Sm4Context();
        byte[] bytes = sm4Context.decryptByCBC(hexToByte(ciphertext), decryptKey.getBytes(StandardCharsets.UTF_8), iv.getBytes(StandardCharsets.UTF_8));
        return new String(bytes);
    }

    /**
     * 字节数组转换为十六进制字符串
     *
     * @param bytes 需要转换的字节数组
     * @return String 十六进制字符串
     */
    private static String byteToHex(byte[] bytes) {
        if (bytes == null) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(b & 0xFF);
            if (hex.length() < 2) {
                hex = "0" + hex;
            }
            sb.append(hex);
        }
        return sb.toString();
    }

    /**
     * 十六进制串转化为byte数组
     *
     * @return 字节数组
     */
    private static byte[] hexToByte(String hex) throws IllegalArgumentException {
        if (hex.length() % 2 != 0) {
            throw new IllegalArgumentException();
        }
        if (hex.length() < 1) {
            return null;
        } else {
            byte[] result = new byte[hex.length() / 2];
            int j = 0;
            for (int i = 0; i < hex.length(); i += 2) {
                result[j++] = (byte) Integer.parseInt(hex.substring(i, i + 2), 16);
            }
            return result;
        }
    }
}
